package com.xmm.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.xmm.constants.CONSTANTS;

public class Ablum implements Music {
	private String mCodeId = "Ablum" + 
			String.valueOf(System.currentTimeMillis()) +
			String.valueOf(Math.random());
	
	private String mName = null;
	private List<Track> mTracks = new ArrayList<Track>();
	private Map<String, Integer> mTrackIndexMap = new HashMap<String, Integer>();
	
	private long mRunningTime = 0;
	private long mFileSize = 0;
	private double mAverageRating = 0.0;
	
	private Map<String, Object> mProps = null;
	
	public Ablum() {}
	
	public Ablum(String name) {
		mName = name;
		mProps = new HashMap<String, Object>();
	}
	
	public void AddTrack(Track track) {
		mRunningTime = getLength();
		mFileSize = getSize();
		mAverageRating = getAveRating();
		mRunningTime += track.getLength();
		mFileSize += track.getSize();
		mAverageRating = 1.0 * (mAverageRating * mTracks.size() 
						+ track.getAveRating()) / (mTracks.size() + 1);
		setLength(mRunningTime);
		setSize(mFileSize);
		setAveRating(mAverageRating);
		mTrackIndexMap.put(track.getCodeId(), mTracks.size());
		mTracks.add(track);
	}
	
	private Track getTrack(int index) {
		if(index < 0 || index >= mTracks.size()) {
			return null;
		}
		return mTracks.get(index);
	}
	
	public Track getTrack(String codeId) {
		if(codeId == null) return null;
		Integer iIndex = mTrackIndexMap.get(codeId);
		if(iIndex == null) return null;
		int index = iIndex.intValue();
		return getTrack(index);
	}
	
	private Track removeTrack(int index) {
		if(index < 0 || index >= mTracks.size()) {
			return null;
		}
		mRunningTime = getLength();
		mFileSize = getSize();
		mAverageRating = getAveRating();
		Track track = mTracks.get(index);
		mRunningTime -= track.getLength();
		mFileSize -= track.getSize();
		if(mTracks.size() == 1) {
			mAverageRating = 0.0;
		} else {
			mAverageRating = 
				1.0 * (mAverageRating * mTracks.size() 
						- track.getAveRating()) / (mTracks.size() - 1);
		}
		setLength(mRunningTime);
		setSize(mFileSize);
		setAveRating(mAverageRating);
		return mTracks.remove(index);
	}
	
	public Music removeFrom(String codeId) {
		if(codeId == null) return null;
		Integer iIndex = mTrackIndexMap.remove(codeId);
		if(iIndex == null) return null;
		int index = iIndex.intValue();
		return removeTrack(index);
	}
	
	public void setName(String name) {
		mName = name;
	}
	public String getName() {
		return mName;
	}
	

	public void setLength(long length) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_LENGTH_NAME, length);
	}
	public long getLength() {
		Object object = mProps.get(CONSTANTS.TRACK_LENGTH_NAME);
		if(object == null) {
			return 0;
		}
		return (Long)object;
	}
	
	public void setAveRating(double rating) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_RATING_NAME, rating);
	}
	public double getAveRating() {
		Object object = mProps.get(CONSTANTS.TRACK_RATING_NAME);
		if(object == null) {
			return 0.0;
		}
		return (Double)object;
	}

	public void setSize(long sized) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_SIZED_NAME, sized);
	}
	public long getSize() {
		Object object = mProps.get(CONSTANTS.TRACK_SIZED_NAME);
		if(object == null) {
			return 0;
		}
		return (Long)object;
	}
	
	@Override
	public String getCodeId() {
		return mCodeId;
	}

	@Override
	public int getClidrenCount() {
		if(mTracks == null) return 0;
		return mTracks.size();
	}
	
	public Map<String, Object> getAllProps() {
		return mProps;
	}
}
